---@class Battle.AiTree
---@field New fun(root:Battle.AiBehavior,actor:Battle.Actor):Battle.AiTree
local AiTree = Battle.CreateClass("AiTree")
Battle.AiTree = AiTree
function AiTree:ctor(root,actor)
    ---@type Battle.AiBehavior
    self.root = root
    self.root.treeRoot = self
    ---@type Battle.Actor
    self.actor = actor
    self.debug = true
    ---@type Battle.AiBehavior[]
    self.executeList = {}
    ---@type Battle.AiBehavior[]
    self.lastExecuteList = {}
    ---@type Battle.AiBlackboard
    self.blackboard = Battle.AiBlackboard.New()
end

function AiTree:SetRunningAction(action)
    self.runningAction = action
end
function AiTree:Start()
    self.isStop = false
end
function AiTree:Stop()
    self.isStop = true
    for k,v in pairs(self.executeList) do
        if v.status == Battle.AiTreeStatus.RUNNING then
            v:onTerminate()
        end
    end
end
function AiTree:tick(dt)
    if self.isStop then return end
    table.clear(self.lastExecuteList)
    local a = self.executeList
    self.executeList = self.lastExecuteList
    self.lastExecuteList = a

    if self.root then
        self.root:tick(dt)
    end
end

function AiTree:AddExecute(behavior)
    table.insert(self.executeList,behavior)
    local count = #self.executeList
    local num = #self.lastExecuteList
    if num > 0 and self.lastExecuteList[count] ~= self.executeList[count] then
        if count <= num then
            for i = count,num do
                local b = self.lastExecuteList[i]
                if b.status == Battle.AiTreeStatus.RUNNING then
                    b:onTerminate()
                end
            end
            table.clear(self.lastExecuteList)
        end


    end
end



local stack = nil
local root = nil
function AiTree.CLEAR()
    stack = {}
    root = nil
end
local function BEGIN(child,...)
    if root == nil then
        root = child
    end
    child:SetParam(...)
    child:Awake()
    local parent = stack[#stack]
    if parent then
        parent:addChild(child)
    end
    table.insert(stack,child)
end
local function END()
    table.remove(stack)
end
function AiTree.GET_ROOT()
    if stack and #stack > 0 then
        logError("begin end 需成对出现，缺少end数量:"..#stack)
    end
    return root
end
function AiTree.BEGIN_SEQUENCE()
    local s = Battle.AiSequence.New(Battle.BehaviorType.Composite)
    BEGIN(s)
end
function AiTree.END_SEQUENCE()
    END()
end
function AiTree.BEGIN_SELECTOR()
    local s = Battle.AiSelector.New(Battle.BehaviorType.Composite)
    BEGIN(s)
end
function AiTree.END_SELECTOR()
    END()
end

---@param type Battle.AiDecoratorType
function AiTree.BEGIN_DECORATOR(type,...)
    local s = type.clazz.New(Battle.BehaviorType.Decorator)
    BEGIN(s,...)
end
function AiTree.END_DECORATOR()
    END()
end
---@param type Battle.AiConditionType
function AiTree.BEGIN_CONDITION(type,...)
    local s = type.clazz.New(Battle.BehaviorType.Condition)
    BEGIN(s,...)
end
function AiTree.END_CONDITION()
    END()
end
---@param type Battle.AiActionType
function AiTree.ADD_ACTION(type,...)
    local node = type.clazz.New(Battle.BehaviorType.Action)
    node:SetParam(...)
    node:Awake()
    local parent = stack[#stack]
    if parent == nil and root == nil then
        root = node
        return
    end
    if parent == nil then
        logError("多重节点请使用\"符合\"节点")
    end
    parent:addChild(node)
end